treeview: Add _gtk_rbtree_find_index()
authorBenjamin Otte <otte@redhat.com>
Thu, 7 Jul 2011 07:52:24 +0000 (09:52 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 16 Nov 2011 03:31:06 +0000 (04:31 +0100)
Uses the parity to do an O(log N) search for the nth element in the
tree in display order of the treeview.

gtk/gtkrbtree.c
gtk/gtkrbtree.h

index 27c9d84fe4ced5215f4a236dac3611a5d240df7d..c8ff556043968cbb82103f5a354b11fa553233a5 100644 (file)
@@ -1104,6 +1104,56 @@ _gtk_rbtree_find_offset (GtkRBTree  *tree,
   return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
 }
 
+gboolean
+_gtk_rbtree_find_index (GtkRBTree  *tree,
+                        guint       index,
+                        GtkRBTree **new_tree,
+                        GtkRBNode **new_node)
+{
+  GtkRBNode *tmp_node;
+
+  g_assert (tree);
+
+  tmp_node = tree->root;
+  while (tmp_node != tree->nil)
+    {
+      if (tmp_node->left->total_count > index)
+        {
+          tmp_node = tmp_node->left;
+        }
+      else if (tmp_node->total_count - tmp_node->right->total_count <= index)
+        {
+          index -= tmp_node->total_count - tmp_node->right->total_count;
+          tmp_node = tmp_node->right;
+        }
+      else
+        {
+          index -= tmp_node->left->total_count;
+          break;
+        }
+    }
+  if (tmp_node == tree->nil)
+    {
+      *new_tree = NULL;
+      *new_node = NULL;
+      return FALSE;
+    }
+
+  if (index > 0)
+    {
+      g_assert (tmp_node->children);
+
+      return _gtk_rbtree_find_index (tmp_node->children,
+                                     index - 1,
+                                     new_tree,
+                                     new_node);
+    }
+
+  *new_tree = tree;
+  *new_node = tmp_node;
+  return TRUE;
+}
+
 void
 _gtk_rbtree_remove_node (GtkRBTree *tree,
                         GtkRBNode *node)
index 85b3dad60b12b2a8e495b609a8ff32fe569826e0..752fddc57c72b21c7b35af72396534db42f824f5 100644 (file)
@@ -135,6 +135,10 @@ gint       _gtk_rbtree_node_find_offset (GtkRBTree              *tree,
                                         GtkRBNode              *node);
 gint       _gtk_rbtree_node_find_parity (GtkRBTree              *tree,
                                         GtkRBNode              *node);
+gboolean   _gtk_rbtree_find_index       (GtkRBTree              *tree,
+                                        guint                   index,
+                                        GtkRBTree             **new_tree,
+                                        GtkRBNode             **new_node);
 gint       _gtk_rbtree_find_offset      (GtkRBTree              *tree,
                                         gint                    offset,
                                         GtkRBTree             **new_tree,